package com.emm.yixun.website.controller.deal;

//框架包
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import com.emm.yixun.common.model.PriceScheme;
import com.emm.yixun.common.model.ReserveArea;
import com.emm.yixun.common.model.User;
import com.emm.yixun.common.model.dto.ReserveAreaDto;
import com.emm.yixun.common.model.dto.SignedDto;
import com.emm.yixun.common.model.enums.AuditStatusEnum;
import com.emm.yixun.common.page.Page;
import com.emm.yixun.common.response.Response;
import com.emm.yixun.common.response.ResponseList;
import com.emm.yixun.marketing.service.ReserveAreaServiceFacade;
import com.emm.yixun.website.common.ajax.AjaxRes;
import com.emm.yixun.website.common.utils.base.Const;
import com.emm.yixun.website.common.utils.security.ShiroUtil;
import com.emm.yixun.website.controller.base.BaseController;
import com.emm.yixun.website.service.signed.SignedService;
//common
//website
//变化的引用
import com.emm.yixun.website.utils.ExcelUtil;

import net.sf.json.JSONObject;

@Controller
@RequestMapping("/deal/areaRepair/")
public class AreaRepairController extends BaseController<PriceScheme> {
	@Autowired
	private SignedService signedService;
	
	@Autowired
	private ReserveAreaServiceFacade reserveAreaService;

	@RequestMapping(value = "index")
	public String index(ModelMap map,HttpServletRequest request) {
		if (doSecurityIntercept(Const.RESOURCES_TYPE_BUTTON,"deal:reserveArea:list")) {
			// 查询菜单按钮权限
			map.put("permitBtn", getPermissionBtnArray());
			map.put("menu", request.getParameter("menu"));
			return "/deal/arearepair/index";
		}
		return Const.NO_AUTHORIZED_URL;
	}

	// 分页查询
	@RequestMapping(value = "list", method = RequestMethod.POST)
	@ResponseBody
	public Page<SignedDto> list(SignedDto dto, Integer limit, Integer page) {
		/*
		 * 1.判断权限2.调用分页查询接口3.返回信息
		 */
		if (doSecurityIntercept(Const.RESOURCES_TYPE_BUTTON, "deal:reserveArea:list")) {
			try {
				if(dto.getDidTimeAfter()!=null&&!dto.getDidTimeAfter().equals("")){
					dto.setDidTimeAfter(dto.getDidTimeAfter()+" 23:59:59");
				}
				dto.setOrders(" t.create_time desc ");
				User user = ShiroUtil.getCurrentUser();
				dto.setMerchantId(user.getMerchantId());
				dto.setAuditStatus(AuditStatusEnum.SUCCESS.getNo());
				dto.setPermissionUserId(user.getId());
				
				//数据权限资源缓存
				String resourcesCode = dto.getResourcesCode();
        		if(StringUtils.isBlank(resourcesCode)){
        			resourcesCode = ShiroUtil.getDataPermissionResources(dto.getResourcesName());
        			dto.setResourcesCode(resourcesCode);
        		}
        		ShiroUtil.setDataPermissionResources(dto.getResourcesName(), resourcesCode);
				
				Response<Page<SignedDto>> response = signedService.selectSignedDtoList(dto, limit, page);

				if (response.isSuccess()) {
					Page<SignedDto> pages = response.getEntity();
					pages.setPageNumber(page);
					return pages;
				} else {
				}
			} catch (Exception e) {
				logger.error(e.toString(), e);
			}
		}
		return new Page<SignedDto>();
	}
	
	// 导出面积补差
	@RequestMapping(value = "expExcel")
	public void expExcel(HttpServletRequest request, HttpServletResponse response, String value, String ckStatus) {
		response.setContentType("text/html;charset=utf-8"); 
		AjaxRes ar=getAjaxRes();
		/*
		 * 1.判断权限2.调用分页查询接口3.返回信息
		 */
		if (ar.setNoAuth(doSecurityIntercept(Const.RESOURCES_TYPE_BUTTON, "deal:reserveArea:export"))) {
			try {
				request.setCharacterEncoding("utf-8");
		        response.setCharacterEncoding("utf-8");
				SignedDto entity = new SignedDto();
				if(StringUtils.isNotBlank(value)){
					//字符串转义
					//value = new String(value.getBytes("ISO-8859-1"), "UTF-8");
					JSONObject obj = JSONObject.fromObject(value);
					if(StringUtils.isNotBlank(obj.getString("buildingId"))){
						entity.setBuildingId(obj.getString("buildingId"));
					}
					if(StringUtils.isNotBlank(obj.getString("premisesId"))){
						entity.setPremisesId(obj.getString("premisesId"));
					}
					if(StringUtils.isNotBlank(obj.getString("projectId"))){
						if(!"-1".equals(obj.getString("projectId"))){
							entity.setProjectId(Long.parseLong(obj.getString("projectId")));
						}
					}
					if(StringUtils.isNotBlank(obj.getString("unitId"))){
						entity.setUnitId(obj.getString("unitId"));
					}
					if(StringUtils.isNotBlank(obj.getString("roomId"))){
						entity.setRoomId(Long.parseLong(obj.getString("roomId")));
					}
					if(StringUtils.isNotBlank(obj.getString("customerName"))){
						String customerName = obj.getString("customerName");
						System.out.println(customerName+"=====expExcel======"+new String(customerName.getBytes("iso8859-1"), "iso8859-1"));
						if(customerName.equals(new String(customerName.getBytes("iso8859-1"), "iso8859-1"))){
							customerName = new String(customerName.getBytes("iso8859-1"),"utf-8");
					    }
						entity.setCustomerName(customerName);
					}
					if(StringUtils.isNotBlank(obj.getString("didTimeBefore"))){
						entity.setDidTimeBefore(obj.getString("didTimeBefore"));
					}
					if(StringUtils.isNotBlank(obj.getString("didTimeAfter"))){
						entity.setDidTimeAfter(obj.getString("didTimeAfter")+" 23:59:59");
					}
					if(StringUtils.isNotBlank(obj.getString("resourcesCode"))){
						entity.setResourcesCode(obj.getString("resourcesCode"));
					}
					if(StringUtils.isNotBlank(obj.getString("resourcesName"))){
						entity.setResourcesName(obj.getString("resourcesName"));
					}
				}
				if(StringUtils.isNotBlank(ckStatus)){
					entity.setM_auditStatus(ckStatus);
				}
				
				entity.setOrders(" t.create_time desc ");
				User user = ShiroUtil.getCurrentUser();
				entity.setMerchantId(user.getMerchantId());
				entity.setAuditStatus(AuditStatusEnum.SUCCESS.getNo());
				entity.setPermissionUserId(user.getId());
				
				//数据权限资源缓存
				String resourcesCode = entity.getResourcesCode();
        		if(StringUtils.isBlank(resourcesCode)){
        			resourcesCode = ShiroUtil.getDataPermissionResources(entity.getResourcesName());
        			entity.setResourcesCode(resourcesCode);
        		}
        		ShiroUtil.setDataPermissionResources(entity.getResourcesName(), resourcesCode);
				
        		ResponseList<SignedDto> res = signedService.selectAllDto(entity);

				if (res.isSuccess()) {
					List<SignedDto> dtoList = res.getEntity();
					SimpleDateFormat sft = new SimpleDateFormat("yyyy-MM-dd");
					
					//组装导出数据
					String[] name = new String[]{"面积补差"}; //sheet
					List<String[]> headerList = new ArrayList<String[]>(); //表头
					List<List<Map<String, String>>> list = new ArrayList<List<Map<String, String>>>(); //数据
					
					//项目客户推荐表
					String[] header = new String[]{"签约日期","客户名称","房号","合同编号","合同单价","合同总价","计价面积/预测面积","实测面积","面积差","面积补差价格","面积补差后总价","面积补差经办时间","面积补差应收时间"};
					headerList.add(header);
					
					List<Map<String, String>> mapList = new ArrayList<Map<String, String>>();
					for(int i = 0; i < dtoList.size(); i++){
						SignedDto dto = (SignedDto)dtoList.get(i);
						Map<String, String> map = new HashMap<String, String>();
						map.put(header[0]+"_"+i, sft.format(dto.getDidTime()));
						map.put(header[1]+"_"+i, dto.getCustomerName());
						map.put(header[2]+"_"+i, dto.getCombinedName());
						map.put(header[3]+"_"+i, dto.getSignCode());
						map.put(header[4]+"_"+i, dto.getSignPrice()==null?"":dto.getSignPrice()+"");
						map.put(header[5]+"_"+i, dto.getSignAmount()==null?"":dto.getSignAmount()+"");
						map.put(header[6]+"_"+i, dto.getCalculateArea()==null?"":dto.getCalculateArea()+"");
						map.put(header[7]+"_"+i, dto.getMeasuredArea()==null?"":dto.getMeasuredArea()+"");
						map.put(header[8]+"_"+i, dto.getBalanceArea()==null?"":dto.getBalanceArea()+"");
						map.put(header[9]+"_"+i, dto.getMakeBalance()==null?"":dto.getMakeBalance()+"");
						map.put(header[10]+"_"+i, dto.getMeasuredPrice()==null?"":dto.getMeasuredPrice()+"");
						map.put(header[11]+"_"+i, dto.getTrusteesDate()==null?"":sft.format(dto.getTrusteesDate()));
						map.put(header[12]+"_"+i, dto.getReceivableDate()==null?"":sft.format(dto.getReceivableDate()));
						mapList.add(map);
					}
					list.add(mapList);
					//导出excel
					ExcelUtil.exportExcel(list, headerList, name, response);
				} 
			} catch (Exception e) {
				logger.error(e.toString(), e);
			}
		}
	}
	
	@RequestMapping(value="toExcelImport")
	public String toExcelImport(){
		return "/deal/arearepair/import";
	}

	@RequestMapping(value="uploadExcel", method=RequestMethod.POST)
	@ResponseBody
	public AjaxRes uploadExcel(HttpServletRequest request, MultipartFile file){
		AjaxRes ar=getAjaxRes();
    	/*
    	 *1.判断权限 
    	 *2.调用新增接口
    	 *3.返回信息
    	*/
        if(ar.setNoAuth(doSecurityIntercept(Const.RESOURCES_TYPE_BUTTON,"deal:reserveArea:import"))){
			try {
				Map<String, Long> reqMap = new HashMap<String, Long>();
				Map<Long, String> accessCodeMap = new HashMap<Long, String>();
				SimpleDateFormat sft = new SimpleDateFormat("yyyy-MM-dd");
				SignedDto reqDto = new SignedDto();
				ResponseList<SignedDto> res = signedService.allDto(reqDto);
				if(res.getEntity() != null){
					for(SignedDto dto: res.getEntity()){
						StringBuffer sb = new StringBuffer();
						sb.append(sft.format(dto.getDidTime())).append("_").
						   append(dto.getCustomerName()).append("_").
						   append(dto.getCombinedName()).append("_").
						   append(dto.getSignCode()==null?"":dto.getSignCode()).append("_").
						   append(dto.getSignPrice()==null?"":dto.getSignPrice()).append("_").
						   append(dto.getSignAmount()==null?"":dto.getSignAmount()).append("_").
						   append(dto.getCalculateArea()==null?"":dto.getCalculateArea());
						reqMap.put(sb.toString(), dto.getId());
						accessCodeMap.put(dto.getId(), dto.getAccessCode());
					}
				}
				String fileName = file.getOriginalFilename();
				String suffix = fileName.substring(fileName.lastIndexOf(".")+1, fileName.length());
				boolean flag = fileType(suffix);
				if(!flag){
					ar.setFailMsg("请上传正确的excel文件");
					return ar;
				}
				
				//导入excel
				List<Map<String, String>> list = ExcelUtil.importExcel(file.getInputStream(), suffix);
				//将excel的数据导入实体类
				List<SignedDto> resList = new ArrayList<SignedDto>(); //正确的数据
				List<SignedDto> failList = new ArrayList<SignedDto>(); //报错的数据
				for(int i = 0; i < list.size(); i++){
					Map<String, String> map = (Map)list.get(i);
					SignedDto dto = new SignedDto();
					StringBuffer sb = new StringBuffer();
					//经办日期
					if(StringUtils.isNotBlank(map.get("excel_0"))){
						sb.append(map.get("excel_0"));
						dto.setDidTimeBefore(map.get("excel_0"));
					}
					sb.append("_");
					//客户名称
					if(StringUtils.isNotBlank(map.get("excel_1"))){
						sb.append(map.get("excel_1"));
						dto.setCustomerName(map.get("excel_1"));
					}
					sb.append("_");
					//房号
					if(StringUtils.isNotBlank(map.get("excel_2"))){
						sb.append(map.get("excel_2"));
						dto.setCombinedName(map.get("excel_2"));
					}
					sb.append("_");
					//合同编号
					if(StringUtils.isNotBlank(map.get("excel_3"))){
						sb.append(map.get("excel_3"));
						dto.setSignCode(map.get("excel_3"));
					}
					sb.append("_");
					//合同单价
					if(StringUtils.isNotBlank(map.get("excel_4"))){
						sb.append(map.get("excel_4"));
						dto.setSignPrice(new BigDecimal(map.get("excel_4")));
					}
					sb.append("_");
					//合同总价
					if(StringUtils.isNotBlank(map.get("excel_5"))){
						sb.append(map.get("excel_5"));
						dto.setSignAmount(new BigDecimal(map.get("excel_5")));
					}
					sb.append("_");
					//计价面积
					if(StringUtils.isNotBlank(map.get("excel_6"))){
						sb.append(map.get("excel_6"));
						dto.setCalculateArea(new BigDecimal(map.get("excel_6")));
					}
					//实测面积
					if(StringUtils.isNotBlank(map.get("excel_7"))){
						dto.setMeasuredArea(new BigDecimal(map.get("excel_7")));
					}else{
						dto.setFailMsg("实测面积不能为空");
						failList.add(dto);
						continue;
					}
					//面积补差经办时间
					if(StringUtils.isNotBlank(map.get("excel_11"))){
						dto.setTrusteesDate(sft.parse(map.get("excel_11")));
					}else{
						dto.setTrusteesDate(Calendar.getInstance().getTime());
					}
					//面积补差应收时间
					if(StringUtils.isNotBlank(map.get("excel_12"))){
						dto.setReceivableDate(sft.parse(map.get("excel_12")));
					}else{
						dto.setReceivableDate(Calendar.getInstance().getTime());
					}
					//通过map获取到signId
					String value = sb.toString();
					if(reqMap.get(value) != null){
						dto.setId(reqMap.get(value));
						resList.add(dto);
					}else{
						dto.setFailMsg("该房号导出的数据，与实际数据不符");
						failList.add(dto);
					}
				}
				//修改面积补差
				User user = ShiroUtil.getCurrentUser();
				for(SignedDto dto: resList){
					SignedDto resDto = balancePrice(dto); //组装数据
					ReserveAreaDto entity = new ReserveAreaDto();
					entity.setSignedId(dto.getId());
					ResponseList<ReserveArea> areaList = reserveAreaService.findByDto(entity);
					
					entity.setBalanceArea(resDto.getBalanceArea()); //补差面积
					entity.setMakeBalance(resDto.getMakeBalance()); //面积补差金额
					entity.setMeasuredArea(resDto.getMeasuredArea()); //实测面积
					entity.setMeasuredPrice(resDto.getMeasuredPrice()); //实际总价
					entity.setReceivableDate(resDto.getReceivableDate()); //面积补差应收日期
					entity.setTrusteesDate(resDto.getTrusteesDate()); //面积补差经办日期
					
					if(areaList.getEntity() != null ){
						//当已有面积补差数据时，修改原数据
						entity.setUpdateUserId(user.getId());
						Response<Integer> resArea = reserveAreaService.updatebySignedId(entity, true);
						//修改失败时保存到错误数据中
						if(resArea.isSuccess()){
							if(resArea.getEntity() < 1){
								dto.setFailMsg("导入失败,未查询到签约记录");
								failList.add(dto);
							}
						}else{
							dto.setFailMsg("导入失败,请联系管理员");
							failList.add(dto);
						}
					}else{
						//新增
						entity.setMerchantId(user.getMerchantId());
						entity.setCreateUserId(user.getId());
						entity.setUserCode(user.getUserCode());
						entity.setAccessCode(accessCodeMap.get(dto.getId()));
						entity.setAuditStatus(AuditStatusEnum.SUCCESS.getNo());
						entity.setDelFlag("0");
						Response<Integer> resArea = reserveAreaService.importSave(entity);
						if(!resArea.isSuccess()){
							dto.setFailMsg("导入失败,请联系管理员");
							failList.add(dto);
						}
					}
				}
				int total = list.size(); //总条数
				int failCount = failList.size(); //失败条数
				int successCount = total - failCount; //成功条数
		    	//将错误信息保存到Session，待下载后删除
				request.getSession().setAttribute("failList", failList);
				
				Map<String, Integer> arMap = new HashMap<String, Integer>();
				arMap.put("total", total);
				arMap.put("failCount", failCount);
				arMap.put("successCount", successCount);
				ar.setObj(arMap);
				ar.setRes(1);
			} catch (Exception e) {
				logger.debug("面积补差客导入报错====》", e);
				logger.error(e.toString(),e);
				ar.setFailMsg(Const.SAVE_FAIL);
			}
		}
        return ar;
	}
	
	/**
	 * 面积补差计算公式
	 * @return
	 */
	public SignedDto balancePrice(SignedDto dto) {
		BigDecimal calculateArea = dto.getCalculateArea(); //预售面积
		BigDecimal measuredArea = dto.getMeasuredArea(); //实测面积
		BigDecimal signPrice = dto.getSignPrice(); //单价
		BigDecimal ratio = new BigDecimal("0.03"); //比例
		BigDecimal balanceArea = new BigDecimal("0"); //面积差
		BigDecimal balancePrice = new BigDecimal("0"); //面积补差价格
		
		if(measuredArea.compareTo(calculateArea) > 0){
			//预售小于实测
			balanceArea = measuredArea.subtract(calculateArea); //面积差
			BigDecimal balanceRatio = balanceArea.divide(calculateArea, 2, BigDecimal.ROUND_FLOOR); //面积差比例
			if(balanceRatio.compareTo(ratio) > 0){
				/**
				 *情况一：（实测-预售）/预售＞3%
				 *公式：客户需要补差价格=预售*3%*单价
				 *例：实售=105，预售=100，单价=1万元；客户需要补差给销售价格=100*3%*1万元=3万元
				*/
				balancePrice = calculateArea.multiply(ratio).multiply(signPrice);
			}else if(balanceRatio.compareTo(ratio) <= 0){
				/**
				 *情况二：0＜（实测-预售）/预售≤3%
				 *公式：客户需要补差价格=（实测-预售）*单价
				 *例：实售=102，预售=100，单价=1万元；客户需要补差给销售价格=（102-100）1万元=2万元
				*/
				balancePrice = balanceArea.multiply(signPrice);
			}
		}else if(measuredArea.compareTo(calculateArea) < 0){
			//预售大于实测
			balanceArea = calculateArea.subtract(measuredArea); //面积差
			BigDecimal balanceRatio = balanceArea.divide(calculateArea, 2, BigDecimal.ROUND_UP); //面积差比例
			if(balanceRatio.compareTo(ratio) <= 0){
				/**
				 *情况三：-3%≤（实测-预售）/预售＜0
				 *公式：销售需要补差价格=（预售-实测）*单价
				 *例：实售=98，预售=100，单价=1万元；销售需要补差给客户价格=（100-98）1万元=2万元
				*/
				balancePrice = balanceArea.multiply(signPrice).multiply(new BigDecimal("-1"));
			}else if(balanceRatio.compareTo(ratio) > 0){
				/**
				 *情况四：（实测-预售）/预售＜-3%
				 *公式：销售需要补差价格=预售*3%*单价+（预售-实测-预售*3%）*单价*2倍
				 *例：实售=95，预售=100，单价=1万元；销售需要补差给客户价格=100*3%*1万元+（100-95-100*3%）1万元*2倍=7万元
				*/
				BigDecimal calculatePrice = calculateArea.multiply(ratio).multiply(signPrice);
				BigDecimal measuredPrice = balanceArea.subtract(calculateArea.multiply(ratio)).multiply(signPrice).multiply(new BigDecimal("2"));
				balancePrice = (calculatePrice.add(measuredPrice)).multiply(new BigDecimal("-1"));
			}
			balanceArea = balanceArea.multiply(new BigDecimal("-1"));
		}
		
		dto.setBalanceArea(balanceArea);
		dto.setMakeBalance(balancePrice);
		BigDecimal measuredPrice = dto.getSignAmount().add(balancePrice); //合同总价
		dto.setMeasuredPrice(measuredPrice);
		return dto;
	}
	
	//判断是否为excel
	public boolean fileType(String suffix){
		boolean flag = true;
		
		StringBuffer sb = new StringBuffer();
		for(int i=0;i<suffix.length();i++){
            char c = suffix.charAt(i);
            sb.append(Character.toLowerCase(c));
		}
		
		if("xls|xlsx".indexOf(sb.toString()) < 0){
			flag = false;
		}
		return flag;
	}
	
	// 导出面积补差错误信息
	@RequestMapping(value = "expFail")
	public void expFail(HttpServletRequest request, HttpServletResponse response) {
		try {
			List<SignedDto> dtoList = (List<SignedDto>) request.getSession().getAttribute("failList");
			if(dtoList != null){
				SimpleDateFormat sft = new SimpleDateFormat("yyyy-MM-dd");
				//组装导出数据
				String[] name = new String[]{"错误信息"}; //sheet
				List<String[]> headerList = new ArrayList<String[]>(); //表头
				List<List<Map<String, String>>> list = new ArrayList<List<Map<String, String>>>(); //数据
				
				//项目客户推荐表
				String[] header = new String[]{"签约日期","客户名称","房号","合同编号","合同单价","合同总价","计价面积/预测面积","实测面积","面积补差经办时间","面积补差应收时间","错误原因"};
				headerList.add(header);
				
				List<Map<String, String>> mapList = new ArrayList<Map<String, String>>();
				for(int i = 0; i < dtoList.size(); i++){
					SignedDto dto = (SignedDto)dtoList.get(i);
					Map<String, String> map = new HashMap<String, String>();
					map.put(header[0]+"_"+i, dto.getDidTimeBefore());
					map.put(header[1]+"_"+i, dto.getCustomerName());
					map.put(header[2]+"_"+i, dto.getCombinedName());
					map.put(header[3]+"_"+i, dto.getSignCode());
					map.put(header[4]+"_"+i, dto.getSignPrice()==null?"":dto.getSignPrice()+"");
					map.put(header[5]+"_"+i, dto.getSignAmount()==null?"":dto.getSignAmount()+"");
					map.put(header[6]+"_"+i, dto.getCalculateArea()==null?"":dto.getCalculateArea()+"");
					map.put(header[7]+"_"+i, dto.getMeasuredArea()==null?"":dto.getMeasuredArea()+"");
					map.put(header[8]+"_"+i, dto.getTrusteesDate()==null?"":sft.format(dto.getTrusteesDate()));
					map.put(header[9]+"_"+i, dto.getReceivableDate()==null?"":sft.format(dto.getReceivableDate()));
					map.put(header[10]+"_"+i, dto.getFailMsg());
					mapList.add(map);
				}
				list.add(mapList);
				//导出excel
				ExcelUtil.exportExcel(list, headerList, name, response);
			}
		} catch (Exception e) {
			logger.error(e.toString(), e);
		}
	}

}
